package com.vi.hcnetsdk.simpleapp;

import android.app.Fragment;
import android.content.DialogInterface;
import android.graphics.PixelFormat;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;

import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.tabs.TabLayout;

import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
import androidx.appcompat.app.AlertDialog;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.View;
import com.google.android.material.navigation.NavigationView;
import com.hikvision.audio.AudioCodecParam;
import com.hikvision.audio.AudioEngine;
import com.hikvision.audio.AudioEngineParam;
import com.hikvision.audio.AudioEngineCallBack;
import com.hikvision.netsdk.HCNetSDK;
import com.hikvision.netsdk.NET_DVR_AUDIO_CHANNEL;
import com.hikvision.netsdk.NET_DVR_COMPRESSION_AUDIO;
import com.hikvision.netsdk.VoiceDataCallBack;

import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.view.SurfaceView;
import android.widget.Spinner;
import android.widget.Switch;
import android.widget.TextView;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.widget.ToggleButton;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

public class MainActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener,SurfaceHolder.Callback,AlarmFragment.OnListFragmentInteractionListener,ConfigFragment.OnFragmentInteractionListener {
    public final static String DEMOTAG = "SimpleDemo";
    public static final int ADD_TO_LIST = 0x1000;
    public static final int VIDEO_CALL_PROCESS = 0x2000;

    public static int m_StartChan = -1;
    public static int m_UserId = -1;
    public static int m_DeviceType = 1;

    private SurfaceHolder holder;
    private static SurfaceView mPlayView = null;

    private boolean bStart = false;
    private boolean bSave = false;

    private View contentLayout;
    private View content_sub;

    private AlarmFragment mAlarm;
    private ConfigFragment mConfig;
    private Fragment mContent;
    private FragmentManager mFragmentMan;

    private Toolbar mToolbar;
    private Handler mHandler; //处理报警信息
    private Handler mVoiceTalkHandler; //处理对讲事件
    private List<View> mTabItems; //tab页面

    private ToggleButton togglebutton;
    private DataModal.ControlLockData data;
    private DataModal.CallParams callParams;

    private Timer timer;

    private TextView mVoiceTalkStatus;

    private AudioEngine mAudioEngine = null;
    private boolean mIsTalking = false;
    protected final Object mOpenCloseIntercomLock = new Object();
    private int mVoiceTalkHandle = -1;

    private static final int             DEVICE                      = 0;
    private static final int             CHANNEL                     = 1;

    private static final int             AUDIO_RECORD                = 0;
    private static final int             AUDIO_PLAY                  = 1;

    private static final int             SDK_AUDIO_TYPE_G722         = 0;
    private static final int             SDK_AUDIO_TYPE_G711_U       = 1;
    private static final int             SDK_AUDIO_TYPE_G711_A       = 2;
    private static final int             SDK_AUDIO_TYPE_G726         = 6;
    private static final int             SDK_AUDIO_TYPE_MP2L2        = 5;
    private static final int             SDK_AUDIO_TYPE_AAC          = 7;

    private static final int             AUDIO_SAMPLERATE_DEF_INDEX  = 0;
    private static final int             AUDIO_SAMPLERATE_16K_INDEX  = 1;
    private static final int             AUDIO_SAMPLERATE_32K_INDEX  = 2;
    private static final int             AUDIO_SAMPLERATE_48K_INDEX  = 3;
    private static final int             AUDIO_SAMPLERATE_44K_INDEX  = 4;
    private static final int             AUDIO_SAMPLERATE_8K_INDEX   = 5;

    private static final int             AUDIO_BITRATE_DEF_INDEX     = 0;
    private static final int             AUDIO_BITRATE_8K_INDEX      = 1;
    private static final int             AUDIO_BITRATE_16K_INDEX     = 2;
    private static final int             AUDIO_BITRATE_32K_INDEX     = 3;
    private static final int             AUDIO_BITRATE_64K_INDEX     = 4;
    private static final int             AUDIO_BITRATE_128K_INDEX    = 5;
    private static final int             AUDIO_BITRATE_192K_INDEX    = 6;
    private static final int             AUDIO_BITRATE_40K_INDEX     = 7;
    private static final int             AUDIO_BITRATE_48K_INDEX     = 8;
    private static final int             AUDIO_BITRATE_56K_INDEX     = 9;
    private static final int             AUDIO_BITRATE_80K_INDEX     = 10;
    private static final int             AUDIO_BITRATE_96K_INDEX     = 11;
    private static final int             AUDIO_BITRATE_122K_INDEX    = 12;
    private static final int             AUDIO_BITRATE_144K_INDEX    = 13;
    private static final int             AUDIO_BITRATE_160K_INDEX    = 14;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //set view context
        setContentView(R.layout.activity_main);

        Log.i(DEMOTAG,"onCreate main Activity");

        initView(savedInstanceState);
        initAlarmHandler();
        initVoiceTalkHandler();
        initMainPage();

        //设置报警处理handler
        DeviceManage.getInstance().setHandler(mHandler, mVoiceTalkHandler);
    }

    // UI references init
    private void initView(Bundle savedInstanceState)
    {
        mToolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(mToolbar);

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer, mToolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.setDrawerListener(toggle);
        toggle.syncState();

        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);

        //预览页面显示
        View appBarLayout = (View) findViewById(R.id.app_bar_main);
        contentLayout = (View)appBarLayout.findViewById(R.id.content_main);
        content_sub = (View)appBarLayout.findViewById(R.id.content);
        mPlayView = (SurfaceView)contentLayout.findViewById(R.id.sur_player);
        holder = mPlayView.getHolder();
        holder.addCallback(this);
        mPlayView.setZOrderOnTop(true);
        mPlayView.setZOrderMediaOverlay(false);

        //fragment显示页面
        content_sub = (View) findViewById(R.id.content);
        //先设置隐藏，把控件都加到fragment管理器中
        content_sub.setVisibility(View.GONE);
        if (savedInstanceState == null) {
            mFragmentMan = getFragmentManager();
            FragmentTransaction transaction = mFragmentMan.beginTransaction();
            mAlarm = new AlarmFragment();
            mConfig = new ConfigFragment();
            transaction.add(R.id.content, mAlarm);
            transaction.add(R.id.content, mConfig);
            transaction.commit();

            data = new DataModal.ControlLockData();
            callParams = new DataModal.CallParams();
        }
    }

    public void switchContent(Fragment from, Fragment to) {
        content_sub.setVisibility(View.VISIBLE);
        if (mContent != to) {
            mContent = to;
            FragmentTransaction transaction = mFragmentMan.beginTransaction().setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out);
            if (!to.isAdded()) {    // 先判断是否被add过
                transaction.hide(from).add(R.id.content, to).commit(); // 隐藏当前的fragment，add下一个到Activity中
            } else {
                transaction.hide(from).show(to).commit(); // 隐藏当前的fragment，显示下一个
            }
        }
    }

    // 停止定时器
    private void stopTimer(){
        if(timer != null){
            timer.cancel();
            // 一定设置为null，否则定时器不会被回收
            timer = null;
        }
    }

    private void initVoiceTalkHandler()
    {
        mVoiceTalkHandler = new Handler() {
            public void handleMessage(android.os.Message msg) {
                switch (msg.what){
                    case VIDEO_CALL_PROCESS:
                        if (msg.obj instanceof DataModal.CallParams) {
                            DataModal.CallParams param = (DataModal.CallParams)msg.obj;
                            switch (param.commandType)
                            {
                                case REQUEST_CALL:
                                    //设备端请求呼叫
                                    mVoiceTalkStatus.setText("The other party initiates Talk request");
                                    // 初始化定时器
                                    if(timer == null) {
                                        timer = new Timer();
                                        timer.schedule(new TimerTask() {
                                            @Override
                                            public void run() {
                                                //发送超时命令
                                                DeviceManage.getInstance().sendSessionCtrlCmd(DeviceManage.VI_CTRL_COMMAND.NO_ANSWER_TIMEOUT);
                                                //关闭对讲
                                                DeviceManage.getInstance().stopVoiceTalk();
                                                DeviceManage.getInstance().stopSinglePreview();
                                            }
                                        }, 0, 30 * 1000);//30s超时
                                    }
                                    break;
                                case CANCLE_CALL:
                                    stopTimer();
                                    //关闭对讲
                                    DeviceManage.getInstance().stopVoiceTalk();
                                    DeviceManage.getInstance().stopSinglePreview();
                                    mVoiceTalkStatus.setText("The other party Cancel Talk");
                                    break;
                                case ANSWER_CALL:
                                    Log.i(DEMOTAG, "m_UserId: "+ m_UserId + "  m_StartChan: "+ m_StartChan+ " m_DeviceType: "+ m_DeviceType);
                                    if(!isTalking())
                                    {
                                        startVoiceTalk(m_UserId,m_StartChan,m_DeviceType);
                                    }
                                    if(!bStart)
                                    {
                                        DeviceManage.getInstance().startSinglePreview(mPlayView);
                                        bStart = true;
                                    }
                                    mVoiceTalkStatus.setText("On the phone...");
                                    break;
                                case REJECT_CALL:
                                    mVoiceTalkStatus.setText("The other party Refuse to answer");
                                    break;
                                case NO_ANSWER_TIMEOUT:
                                    mVoiceTalkStatus.setText("No answer");
                                    break;
                                case HANG_UP:
                                    //关闭对讲
                                    DeviceManage.getInstance().stopVoiceTalk();
                                    DeviceManage.getInstance().stopSinglePreview();
                                    mVoiceTalkStatus.setText("The other party hang up");
                                    break;
                                case DEVICE_BUSY:
                                    DeviceManage.getInstance().stopVoiceTalk();
                                    DeviceManage.getInstance().stopSinglePreview();
                                    mVoiceTalkStatus.setText("The other party busy");
                                    break;
                                //case CLIENT_BUSY:
                                //    DeviceManage.getInstance().sendSessionCtrlCmd(DeviceManage.VI_CTRL_COMMAND.CLIENT_BUSY);
                                //    mVoiceTalkStatus.setText("busy");
                                //   break;
                                case INDOOR_UNIT_OFFLINE:
                                    DeviceManage.getInstance().stopVoiceTalk();
                                    DeviceManage.getInstance().stopSinglePreview();
                                    mVoiceTalkStatus.setText("The indoor unit offline");
                                    break;
                                default:
                                    break;
                            }
                        } else {
                            int iStatus = (int)msg.obj;
                            Log.i(DEMOTAG, "Voice talk status" + iStatus);
                        }
                        break;
                    default:break;
                }
            };
        };
    }

    private void initAlarmHandler()
    {
        mHandler = new Handler() {
            public void handleMessage(android.os.Message msg) {
                switch (msg.what){
                    case ADD_TO_LIST:
                        if (msg.obj instanceof AlarmContent.AlarmItem && mAlarm != null && mAlarm.mAlarmAdapter != null) {
                            if(mAlarm.mAlarmAdapter.getItemCount() > 4000)
                                mAlarm.mAlarmAdapter.removeAllData();
                            addData((AlarmContent.AlarmItem) msg.obj);
                        }
                        break;
                    default:break;
                }
            };
        };
    }

    private void initMainPage()
    {
        mTabItems = new ArrayList<View>();
        View view = getLayoutInflater().inflate(R.layout.tabitem_control, null);
        mTabItems.add(view);
        view = getLayoutInflater().inflate(R.layout.tabitem_lock, null);
        mTabItems.add(view);
        view = getLayoutInflater().inflate(R.layout.tabitem_talk, null);
        mTabItems.add(view);

        //预览布防页面
        Button start = (Button) mTabItems.get(0).findViewById(R.id.btn_start_pr);
        start.setOnClickListener(StartPreview_Listener);
        Button stop = (Button)mTabItems.get(0).findViewById(R.id.btn_stop_pr);
        stop.setOnClickListener(StopPreview_Listener);
        togglebutton = (ToggleButton) mTabItems.get(0).findViewById(R.id.toggleButton);
        togglebutton.setOnClickListener(Alarm_Listener);

        //远程开锁页面
        Spinner spin = (Spinner) mTabItems.get(1).findViewById(R.id.spinner);
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource( this, R.array.locktype_arry, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spin.setAdapter(adapter);
        spin.setOnItemSelectedListener(ItemSelect_listener);

        Spinner spin2 = (Spinner) mTabItems.get(1).findViewById(R.id.spinner_control_type);
        ArrayAdapter<CharSequence> adapter2 = ArrayAdapter.createFromResource( this, R.array.lockscene_arry, android.R.layout.simple_spinner_item);
        adapter2.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spin2.setAdapter(adapter2);
        spin2.setOnItemSelectedListener(ItemSelect_listener);
        Button operate = (Button) mTabItems.get(1).findViewById(R.id.btn_open_lock);
        operate.setOnClickListener(OpenLock_Listener);

        //可视对讲页面
        Button startVedioIntercome = (Button) mTabItems.get(2).findViewById(R.id.btn_start_vt);
        startVedioIntercome.setOnClickListener(StartVI_Listener);
        mVoiceTalkStatus = (TextView) mTabItems.get(2).findViewById(R.id.tv_voice_talk_status);
        Button stopVedioIntercome = (Button) mTabItems.get(2).findViewById(R.id.btn_stop_vt);
        stopVedioIntercome.setOnClickListener(StopVI_Listener);
        Button sendCmd = (Button) mTabItems.get(2).findViewById(R.id.btn_call);
        sendCmd.setOnClickListener(SendControlCmd_Listener);
        Button sendCmd2 = (Button) mTabItems.get(2).findViewById(R.id.btn_answer);
        sendCmd2.setOnClickListener(SendControlCmd_Listener);
        Button sendCmd3 = (Button) mTabItems.get(2).findViewById(R.id.btn_hangup);
        sendCmd3.setOnClickListener(SendControlCmd_Listener);
        Button sendCmd4 = (Button) mTabItems.get(2).findViewById(R.id.btn_reject);
        sendCmd4.setOnClickListener(SendControlCmd_Listener);

        ViewPager viewPager = (ViewPager) findViewById(R.id.vp_pager);
        MainPageAdapter myAdapter = new MainPageAdapter(mTabItems);
        viewPager.setAdapter(myAdapter);

        TabLayout tabLayout = (TabLayout) findViewById(R.id.tabLayout_main);
        tabLayout.setupWithViewPager(viewPager);
    }
    @Override
    protected void onStart() {
        Log.i(DEMOTAG, "MainActivity onStart");
        super.onStart();
    }
    @Override
    protected void onRestart() {
        Log.i(DEMOTAG, "MainActivity onRestart");
        super.onRestart();
        bSave = true;
    }
    @Override
    protected void onResume() {
        Log.i(DEMOTAG, "MainActivity onResume");
        super.onResume();
    }
    @Override
    protected void onPause() {
        Log.i(DEMOTAG, "MainActivity onPause");
        super.onPause();
    }
    @Override
    protected void onStop() {
        Log.i(DEMOTAG, "MainActivity onStop");
        super.onStop();
    }
    @Override
    protected void onDestroy() {
        Log.i(DEMOTAG, "MainActivity onDestroy");
        super.onDestroy();
        DeviceManage.getInstance().stopAlarm();
        DeviceManage.getInstance().logout();
        mAlarm.mRecyclerView.removeAllViews();
        mAlarm.mAlarmAdapter.removeAllData();
    }

    //报警信息点击Item响应函数，暂时未用
    @Override
    public void onListFragmentInteraction(AlarmContent.AlarmItem item)
    {
        Log.i(DEMOTAG, "content selected");
    }

    @Override
    public void onFragmentInteraction(Uri uri)
    {
        Log.i(DEMOTAG, "Fragment worked");
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        if(bStart && bSave) {
            DeviceManage.getInstance().startSinglePreview(mPlayView);
            bSave = false;
        }
        Log.i(DEMOTAG, "surface is created");
        if (!holder.getSurface().isValid()) {
            Log.e(DEMOTAG, "Player setVideoWindow failed!");
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        if (bStart) {
            DeviceManage.getInstance().stopSinglePreview();
        }
        Log.i(DEMOTAG, "Player setVideoWindow release!");
        if (!holder.getSurface().isValid()) {
            Log.e(DEMOTAG, "Player setVideoWindow failed!");
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
                               int height) {
        holder.setFormat(PixelFormat.TRANSLUCENT);
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putBoolean("bSave", bSave);
        Log.i(DEMOTAG, "main activity onSaveInstanceState");
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        bSave = savedInstanceState.getBoolean("bSave");
        Log.i(DEMOTAG, "main activity onRestoreInstanceState");
        super.onRestoreInstanceState(savedInstanceState);
    }


    // Start vedio intercome interaction
    private  Button.OnClickListener StartVI_Listener = new Button.OnClickListener(){
        @Override
        public void onClick(View view){
//            Dialog bottomDialog = new Dialog(view.getContext(), R.style.BottomDialog);
//            View contentView = LayoutInflater.from(view.getContext()).inflate(R.layout.dialog_content_normal, null);
//            bottomDialog.setContentView(contentView);
//            ViewGroup.LayoutParams layoutParams = contentView.getLayoutParams();
//            layoutParams.width = getResources().getDisplayMetrics().widthPixels;
//            contentView.setLayoutParams(layoutParams);
//            bottomDialog.getWindow().setGravity(Gravity.BOTTOM);
//            bottomDialog.getWindow().setWindowAnimations(R.style.BottomDialog_Animation);
//            bottomDialog.show();

            if (callParams == null) {
                callParams = new DataModal.CallParams();
            }

            // 创建对话框构建器
            AlertDialog.Builder dialog =  new AlertDialog.Builder(view.getContext());
            // 获取布局
            View view2Display = View.inflate(MainActivity.this, R.layout.dialog_call_params, null);
            // 获取布局中的控件
            final EditText periodNo = (EditText) view2Display.findViewById(R.id.tv_period_no);
            final EditText buildingNo = (EditText) view2Display.findViewById(R.id.tv_building_number);
            final EditText unitNo = (EditText) view2Display.findViewById(R.id.tv_unit_number);
            final EditText floorNo = (EditText) view2Display.findViewById(R.id.tv_floor_number);
            final EditText roomNo = (EditText) view2Display.findViewById(R.id.tv_room_number);
            final EditText deviceNo = (EditText) view2Display.findViewById(R.id.tv_device_number);

            final Spinner spin2 = (Spinner) view2Display.findViewById(R.id.spinner_device_type);
            ArrayAdapter<CharSequence> adapter2 = ArrayAdapter.createFromResource(MainActivity.this, R.array.device_type_arry, android.R.layout.simple_spinner_item);
            adapter2.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            spin2.setAdapter(adapter2);
            spin2.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                @Override
                public void onItemSelected(AdapterView<?> parent, View view,
                                           int position, long id) {
                    callParams.deviceType = position + 1;
                }
                @Override
                public void onNothingSelected(AdapterView<?> parent) {
                    // TODO Auto-generated method stub
                }
            });

            // 设置参数
            dialog.setTitle("呼叫设备参数").setView(view2Display)
                    .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            callParams.period = (short)Integer.parseInt(periodNo.getText().toString());
                            callParams.buildingNumber = (short)Integer.parseInt(buildingNo.getText().toString());
                            callParams.unitNumber = (short)Integer.parseInt(unitNo.getText().toString());
                            callParams.foorNumber = (short)Integer.parseInt(floorNo.getText().toString());
                            callParams.roomNumber = (short)Integer.parseInt(roomNo.getText().toString());
                            callParams.deviceIndex = (short)Integer.parseInt(deviceNo.getText().toString());

                            mVoiceTalkStatus.setText("Start Session...");
                            //fix:return value check
                            DeviceManage.getInstance().startVideoCallSession();
                            DeviceManage.getInstance().setCallParams(callParams);

                            //开启语音对讲和可视化对讲
                            Log.i(DEMOTAG, "m_UserId: "+ m_UserId + "  m_StartChan: "+ m_StartChan+ " m_DeviceType: "+ m_DeviceType);
//                            if(!isTalking())
//                            {
//                                startVoiceTalk(m_UserId,m_StartChan,m_DeviceType);
//                            }
//                            if(!bStart)
//                            {
//                                DeviceManage.getInstance().startSinglePreview(mPlayView);
//                                bStart = true;
//                            }
                            dialog.dismiss();
                        }
                    })
                    .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.dismiss();// 对话框消失
                        }
                    });
            //String uname = username.getText().toString().trim();

            // 创建对话框
            final AlertDialog alertDialog = dialog.create();

            alertDialog.show();
        }
    };


    //stop vedio intercome
    private Button.OnClickListener StopVI_Listener = new Button.OnClickListener(){
        @Override
        public void onClick(View view) {
            //mVoiceTalkStatus.setText("Close Session...");
            //DeviceManage.getInstance().stopVideoCallSession();
            //mVoiceTalkStatus.setText("");
            //停止发送信令
            DeviceManage.getInstance().stopVideoCallSession();
            synchronized (mOpenCloseIntercomLock) {
                if (!isTalking()) {
                    return ;
                }

                stopRecordOrPlay(AUDIO_RECORD);
                stopNetSDKVoiceCom();
                stopRecordOrPlay(AUDIO_PLAY);
                mAudioEngine.close();
                //将语音对讲状态置为false
                setTalkStatus(false);
                //关闭预览
                if(bStart)
                {
                    DeviceManage.getInstance().stopSinglePreview();
                    bStart = false;
                }
                mPlayView.setVisibility(View.GONE);
                mPlayView.setVisibility(View.VISIBLE);

                mVoiceTalkStatus.setText("Stop Vocie Talk");
                return ;
            }
        }
    };

    public void stopNetSDKVoiceCom()
    {
        if (mVoiceTalkHandle >= 0)
        {
            HCNetSDK.getInstance().NET_DVR_StopVoiceCom(mVoiceTalkHandle);
            mVoiceTalkHandle = -1;
        }
    }


    public void setTalkStatus(boolean isTalking)
    {
        mIsTalking = isTalking;
    }

    public boolean isTalking()
    {
        return mIsTalking;
    }

    public boolean isAudioSupportType(NET_DVR_COMPRESSION_AUDIO audioCompression, int type)
    {
        int audioType = audioCompression.byAudioEncType;
        switch (audioType)
        {
            case SDK_AUDIO_TYPE_G722:
            case SDK_AUDIO_TYPE_G711_U:
            case SDK_AUDIO_TYPE_G711_A:
            case SDK_AUDIO_TYPE_G726:
                return true;
            case SDK_AUDIO_TYPE_MP2L2:
            case SDK_AUDIO_TYPE_AAC:
                if (CHANNEL == type)
                {
                    return false;
                }
                switch (audioCompression.byAudioSamplingRate)
                {
                    case AUDIO_SAMPLERATE_DEF_INDEX:
                    case AUDIO_SAMPLERATE_16K_INDEX:
                    case AUDIO_SAMPLERATE_32K_INDEX:
                    case AUDIO_SAMPLERATE_48K_INDEX:
                    case AUDIO_SAMPLERATE_44K_INDEX:
                    case AUDIO_SAMPLERATE_8K_INDEX:
                        break;
                    default:
                        return false;
                }
                switch (audioCompression.byAudioBitRate)
                {
                    case AUDIO_BITRATE_DEF_INDEX:
                    case AUDIO_BITRATE_8K_INDEX:
                    case AUDIO_BITRATE_16K_INDEX:
                    case AUDIO_BITRATE_32K_INDEX:
                    case AUDIO_BITRATE_64K_INDEX:
                    case AUDIO_BITRATE_128K_INDEX:
                    case AUDIO_BITRATE_192K_INDEX:
                    case AUDIO_BITRATE_40K_INDEX:
                    case AUDIO_BITRATE_48K_INDEX:
                    case AUDIO_BITRATE_56K_INDEX:
                    case AUDIO_BITRATE_80K_INDEX:
                    case AUDIO_BITRATE_96K_INDEX:
                    case AUDIO_BITRATE_122K_INDEX:
                    case AUDIO_BITRATE_144K_INDEX:
                    case AUDIO_BITRATE_160K_INDEX:
                        return true;
                    default:
                        return false;
                }
            default:
                return false;
        }
    }

    public boolean startRecordOrPlay(NET_DVR_COMPRESSION_AUDIO audioCompression, int actionType)
    {
        if(mAudioEngine == null)
        {
            Log.i(DEMOTAG,"audio engine is null");
            return false;
        }
        AudioCodecParam param = new AudioCodecParam();
        initAudioParams(audioCompression, param);

        int iErrorCode;
        if (actionType == AUDIO_RECORD)
        {
//            PARAM_MODE_RECORDE
            iErrorCode = mAudioEngine.setAudioParam(param, AudioEngineParam.PARAM_MODE_TYPE.PARAM_MODE_RECORDE);
            if(iErrorCode != 0)
            {
                Log.i(DEMOTAG,"audio.setAudioParam  failed, error:" + iErrorCode);
                return false;
            }
            iErrorCode = mAudioEngine.startRecord();
        }
        else
        {
            iErrorCode = mAudioEngine.setAudioParam(param, AudioEngineParam.PARAM_MODE_TYPE.PARAM_MODE_PLAY);
            if(iErrorCode != 0)
            {
                Log.i(DEMOTAG,"audio.setAudioParam PARAM_MODE_PLAY failed, error:" + iErrorCode);
                return false;
            }
            iErrorCode = mAudioEngine.startPlay();
        }

        if(iErrorCode != 0)
        {
            if(actionType == AUDIO_RECORD)
            {
                Log.i(DEMOTAG,"startRecord  errorCode:" + iErrorCode);
            }
            else
            {
                Log.i(DEMOTAG,"startPlay  errorCode: " + iErrorCode);
            }
            return false;
        }
        return true;
    }

    public void initAudioParams(NET_DVR_COMPRESSION_AUDIO audioCompression, AudioCodecParam param)
    {
        int audioType = audioCompression.byAudioEncType;
        switch (audioType)
        {
            case SDK_AUDIO_TYPE_G722:
                param.nCodecType = AudioCodecParam.AudioEncodeType.AUDIO_TYPE_G722;
                param.nSampleRate = AudioCodecParam.AudioSampleRate.AUDIO_SAMPLERATE_16K;
                param.nBitRate = AudioCodecParam.AudioBitRate.AUDIO_BITRATE_16K;
                break;
            case SDK_AUDIO_TYPE_G711_U:
                param.nCodecType = AudioCodecParam.AudioEncodeType.AUDIO_TYPE_G711U;
                param.nSampleRate = AudioCodecParam.AudioSampleRate.AUDIO_SAMPLERATE_8K;
                param.nBitRate = AudioCodecParam.AudioBitRate.AUDIO_BITRATE_64K;
                break;
            case SDK_AUDIO_TYPE_G711_A:
                param.nCodecType = AudioCodecParam.AudioEncodeType.AUDIO_TYPE_G711A;
                param.nSampleRate = AudioCodecParam.AudioSampleRate.AUDIO_SAMPLERATE_8K;
                param.nBitRate = AudioCodecParam.AudioBitRate.AUDIO_BITRATE_64K;
                break;
            case SDK_AUDIO_TYPE_G726:
                param.nCodecType = AudioCodecParam.AudioEncodeType.AUDIO_TYPE_G726;
                param.nSampleRate = AudioCodecParam.AudioSampleRate.AUDIO_SAMPLERATE_8K;
                param.nBitRate = AudioCodecParam.AudioBitRate.AUDIO_BITRATE_16K;
                break;
            case SDK_AUDIO_TYPE_MP2L2:
                param.nCodecType = AudioCodecParam.AudioEncodeType.AUDIO_TYPE_MPEG2;
                param.nSampleRate = parseSamplingRate(audioCompression.byAudioSamplingRate);
                param.nBitRate = parseBitRate(audioCompression.byAudioBitRate);
                Log.i(DEMOTAG,"MP2L2 param.nBitRate:" + param.nBitRate);
                Log.i(DEMOTAG,"MP2L2 param.nSampleRate:" + param.nSampleRate);
                break;
            case SDK_AUDIO_TYPE_AAC:
                param.nCodecType = AudioCodecParam.AudioEncodeType.AUDIO_TYPE_AAC;
                param.nSampleRate = parseSamplingRate(audioCompression.byAudioSamplingRate);
                param.nBitRate = parseBitRate(audioCompression.byAudioBitRate);
                Log.i(DEMOTAG,"AAC param.nBitRate:" + param.nBitRate);
                Log.i(DEMOTAG,"AAC param.nSampleRate:" + param.nSampleRate);
                break;
            default:
                break;
        }

        param.nBitWidth = AudioCodecParam.AudioBitWidth.AUDIO_WIDTH_16BIT;
        param.nChannel = AudioCodecParam.AudioChannel.AUDIO_CHANNEL_MONO;
    }

    public int parseBitRate(int byAudioBitRate)
    {
        switch (byAudioBitRate)
        {
            case AUDIO_BITRATE_8K_INDEX:
                return AudioCodecParam.AudioBitRate.AUDIO_BITRATE_8K;
            case AUDIO_BITRATE_DEF_INDEX:
            case AUDIO_BITRATE_16K_INDEX:
                return AudioCodecParam.AudioBitRate.AUDIO_BITRATE_16K;
            case AUDIO_BITRATE_32K_INDEX:
                return AudioCodecParam.AudioBitRate.AUDIO_BITRATE_32K;
            case AUDIO_BITRATE_64K_INDEX:
                return AudioCodecParam.AudioBitRate.AUDIO_BITRATE_64K;
            case AUDIO_BITRATE_128K_INDEX:
                return AudioCodecParam.AudioBitRate.AUDIO_BITRATE_128K;
            case AUDIO_BITRATE_192K_INDEX:
                return AudioCodecParam.AudioBitRate.AUDIO_BITRATE_192K;
            case AUDIO_BITRATE_40K_INDEX:
                return AudioCodecParam.AudioBitRate.AUDIO_BITRATE_40K;
            case AUDIO_BITRATE_48K_INDEX:
                return AudioCodecParam.AudioBitRate.AUDIO_BITRATE_48K;
            case AUDIO_BITRATE_56K_INDEX:
                return AudioCodecParam.AudioBitRate.AUDIO_BITRATE_56K;
            case AUDIO_BITRATE_80K_INDEX:
                return AudioCodecParam.AudioBitRate.AUDIO_BITRATE_80K;
            case AUDIO_BITRATE_96K_INDEX:
                return AudioCodecParam.AudioBitRate.AUDIO_BITRATE_96K;
            case AUDIO_BITRATE_122K_INDEX:
                return AudioCodecParam.AudioBitRate.AUDIO_BITRATE_112K;
            case AUDIO_BITRATE_144K_INDEX:
                return AudioCodecParam.AudioBitRate.AUDIO_BITRATE_144K;
            case AUDIO_BITRATE_160K_INDEX:
                return AudioCodecParam.AudioBitRate.AUDIO_BITRATE_160K;
            default:
                return AudioCodecParam.AudioSampleRate.AUDIO_SAMPLERATE_16K;
        }
    }

    public int parseSamplingRate(int byAudioSamplingRate)
    {
        switch (byAudioSamplingRate)
        {
            case AUDIO_SAMPLERATE_DEF_INDEX:
            case AUDIO_SAMPLERATE_16K_INDEX:
                return AudioCodecParam.AudioSampleRate.AUDIO_SAMPLERATE_16K;
            case AUDIO_SAMPLERATE_32K_INDEX:
                return AudioCodecParam.AudioSampleRate.AUDIO_SAMPLERATE_32K;
            case AUDIO_SAMPLERATE_48K_INDEX:
                return AudioCodecParam.AudioSampleRate.AUDIO_SAMPLERATE_48K;
            case AUDIO_SAMPLERATE_44K_INDEX:
                return AudioCodecParam.AudioSampleRate.AUDIO_SAMPLERATE_44K;
            case AUDIO_SAMPLERATE_8K_INDEX:
                return AudioCodecParam.AudioSampleRate.AUDIO_SAMPLERATE_8K;
            default:
                return AudioCodecParam.AudioSampleRate.AUDIO_SAMPLERATE_16K;
        }
    }

    public synchronized void stopRecordOrPlay(int actionType)
    {
        if (mAudioEngine == null)
        {
            return;
        }

        if (actionType == AUDIO_RECORD)
        {
            mAudioEngine.stopRecord();
        }
        else
        {
            mAudioEngine.stopPlay();
        }
    }

    public boolean startVoiceTalk(int iUserID, int iChan, int deviceType)
    {
        //get the device current valid audio type
        synchronized (mOpenCloseIntercomLock)
        {
            if(isTalking())
            {
                return true;
            }
            NET_DVR_COMPRESSION_AUDIO compressAud = new NET_DVR_COMPRESSION_AUDIO();
            boolean isSucc;
            if(deviceType == DEVICE)
            {
                isSucc = HCNetSDK.getInstance().NET_DVR_GetCurrentAudioCompress(iUserID, compressAud);
            }
            else
            {
                NET_DVR_AUDIO_CHANNEL ipcChannel = new NET_DVR_AUDIO_CHANNEL();
                ipcChannel.dwChannelNum = iChan;
                isSucc = HCNetSDK.getInstance().NET_DVR_GetCurrentAudioCompress_V50(iUserID, ipcChannel, compressAud);
            }

            if(!isSucc)
            {
                Log.i(DEMOTAG,"NET_DVR_GetCurrentAudioCompress failed, error:" + HCNetSDK.getInstance().NET_DVR_GetLastError());
                return false;
            }

            if (!isAudioSupportType(compressAud, deviceType))
            {
                Log.i(DEMOTAG,"isAudioSupportType: not support");
                return false;
            }

            if(mAudioEngine == null)
            {
                mAudioEngine = new AudioEngine(AudioEngineParam.CAE_MODE_TYPE.CAE_INTERCOM);
            }

            //open audio engine
            int errorCode = mAudioEngine.open();
            if(errorCode != 0)
            {
                Log.i(DEMOTAG,"audio engine open failed, error:" + errorCode);
                return false;
            }

            if (!startRecordOrPlay(compressAud, AUDIO_PLAY))
            {
                return false;
            }

            VoiceDataCallBack voiceDataCallBack = new VoiceDataCallBack()
            {
                public void fVoiceDataCallBack(int lVoiceComHandle, byte[] pDataBuffer, int iDataSize, int iAudioFlag)
                {
                    Log.i(DEMOTAG,"inputData into AudioEngienSDK,Len: " + iDataSize+ "\n");
                    inputData(pDataBuffer, iDataSize);
                }
            };

            if (!startNetSDKVoiceCom(iUserID, iChan, voiceDataCallBack))
            {
                stopRecordOrPlay(AUDIO_PLAY);
                return false;
            }


            AudioEngineCallBack.RecordDataCallBack recordDataCallBack = new AudioEngineCallBack.RecordDataCallBack()
            {
                public void onRecordDataCallBack(int dwEncodeType, byte[] data, int len)
                {
//                    Log.i(DEMOTAG,"voiceComSendData Len: " + len + "\n  data: " + new String(data) + "\n");
                    voiceComSendData(data, len);
                }
            };

            mAudioEngine.setAudioCallBack(recordDataCallBack, AudioEngineParam.DATA_CALLBACK_TYPE.RECORDE_DATA_CALLBACK);

            if (!startRecordOrPlay(compressAud, AUDIO_RECORD))
            {
                mVoiceTalkHandle = -1;
                return false;
            }

            setTalkStatus(true);

            return true;
        }
    }

    public boolean voiceComSendData(byte[] pSendBuf, int lBufSize)
    {
        if(!isTalking())
        {
            return true;
        }
        if (-1 == mVoiceTalkHandle)
        {
            System.out.println("startVoiceCom order error");
            return false;
        }

        if (!HCNetSDK.getInstance().NET_DVR_VoiceComSendData(mVoiceTalkHandle, pSendBuf, lBufSize))
        {
            int sdkError = HCNetSDK.getInstance().NET_DVR_GetLastError();
            Log.i(DEMOTAG,"NET_DVR_VoiceComSendData failed! SDK error: " + sdkError);
            return false;
        }
        Log.i(DEMOTAG,"NET_DVR_VoiceComSendData Success: lBufSize: " + lBufSize + "  pSendBuf:  "+ pSendBuf.toString() + "\n");

        return true;
    }


    public boolean startNetSDKVoiceCom(int userID, int voiceChan, VoiceDataCallBack callBack)
    {
        if (mVoiceTalkHandle >= 0)
        {
            return false;
        }
        mVoiceTalkHandle = HCNetSDK.getInstance().NET_DVR_StartVoiceCom_MR_V30(userID, voiceChan, callBack);
        if (-1 == mVoiceTalkHandle)
        {
            return false;
        }
        return true;
    }

    public int inputData(byte[] audioData, int len)
    {
        if(!isTalking())
        {
            return 0;
        }
        if (mAudioEngine == null)
        {
            return -1;
        }
        int ret = mAudioEngine.inputData(audioData, len);
        if(ret != 0) {
            Log.i(DEMOTAG, "AudioEngine inputData failed : " + ret);
        }
        return ret;
    }

    //Send command
    private Button.OnClickListener SendControlCmd_Listener = new Button.OnClickListener(){
        @Override
        public void onClick(View view) {
            int id = view.getId();
            switch (id)
            {
                case R.id.btn_answer:
                    DeviceManage.getInstance().sendSessionCtrlCmd(DeviceManage.VI_CTRL_COMMAND.ANSWER_CALL);
                    Log.i(DEMOTAG, "m_UserId: "+ m_UserId + "  m_StartChan: "+ m_StartChan+ " m_DeviceType: "+ m_DeviceType);
                    if(!isTalking())
                    {
                        startVoiceTalk(m_UserId,m_StartChan,m_DeviceType);
                    }
                    //如果没开启预览，便开启预览
                    if(!bStart)
                    {
                        DeviceManage.getInstance().startSinglePreview(mPlayView);
                        bStart = true;
                    }
                    mVoiceTalkStatus.setText("On the phone");
                    break;
                case R.id.btn_call:
                    DeviceManage.getInstance().sendSessionCtrlCmd(DeviceManage.VI_CTRL_COMMAND.REQUEST_CALL);
                    mVoiceTalkStatus.setText("Calling...");
                    break;
                case R.id.btn_reject:
                    DeviceManage.getInstance().sendSessionCtrlCmd(DeviceManage.VI_CTRL_COMMAND.REJECT_CALL);
                    mVoiceTalkStatus.setText("Refuse to answer");
                    break;
                case R.id.btn_hangup:
                    DeviceManage.getInstance().stopVoiceTalk();
                    DeviceManage.getInstance().stopSinglePreview();
                    DeviceManage.getInstance().sendSessionCtrlCmd(DeviceManage.VI_CTRL_COMMAND.HANG_UP);
                    mVoiceTalkStatus.setText("hang up");
                    break;
                default:
                    break;
            }
        }
    };

    // Start Preview listener
    private Button.OnClickListener OpenLock_Listener = new Button.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (data == null) {
                data = new DataModal.ControlLockData();
                data.init();
            }

            Switch sw = (Switch)mTabItems.get(1).findViewById(R.id.switch_command);
            if(sw.isChecked()) {
                //开锁
                data.command = 1;
            }else{
                //关锁
                data.command = 0;
            }

            EditText et = (EditText)mTabItems.get(1).findViewById(R.id.et_controlsrc);
            data.control_src = et.getText().toString();

            et = (EditText)mTabItems.get(1).findViewById(R.id.et_lock_id);
            data.lock_id =  Integer.parseInt(et.getText().toString());

            et = (EditText)mTabItems.get(1).findViewById(R.id.et_door_index);
            data.gateway_index =  Integer.parseInt(et.getText().toString());

            //智能锁时密码有效
            if(data.lock_type == 1) {
                et = (EditText)mTabItems.get(1).findViewById(R.id.et_unlock_psw);
                data.passwd = et.getText().toString();
            }

            int iRet = DeviceManage.getInstance().operate_lock(data);
            if(iRet == 0) {
                //正常操作
                Snackbar.make(view, "远程开锁操作成功", Snackbar.LENGTH_SHORT).show();
            }
            else {
                Snackbar.make(view, "远程开锁操作失败，错误码：" + iRet, Snackbar.LENGTH_SHORT).show();
            }
        }
    };

    private Spinner.OnItemSelectedListener ItemSelect_listener = new Spinner.OnItemSelectedListener(){
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position,  long id) {
            if (data == null) {
                data = new DataModal.ControlLockData();
                data.init();
            }

            switch (parent.getId())
            {
                case R.id.spinner:
                    data.lock_type = position;
                    break;
                case R.id.spinner_control_type:
                    data.control_type = position + 1;
                    break;
                default:
                    break;
            }
            //lable.setText(arg0.getItemAtPosition(arg2).toString());
        }
        @Override
        public void onNothingSelected(AdapterView<?> parent) {
        }
    };

    private ToggleButton.OnClickListener Alarm_Listener = new ToggleButton.OnClickListener() {
        @Override
        public void onClick(View view) {
            // 当按钮第一次被点击时候响应的事件
            if (togglebutton.isChecked()) {
                DeviceManage.getInstance().startAlarm(DeviceManage.getInstance().mUserID);
            }
            // 当按钮再次被点击时候响应的事件
            else {
                DeviceManage.getInstance().stopAlarm();
            }
        }
    };

    // Start Preview listener
    private Button.OnClickListener StartPreview_Listener = new Button.OnClickListener() {
        @Override
        public void onClick(View view) {
            if(DeviceManage.getInstance().startSinglePreview(mPlayView))
            {
                bStart = true;
            }
            //                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
            //                        .setAction("Action", null).show();
        }
    };

    // Stop Preview listener
    private Button.OnClickListener StopPreview_Listener = new Button.OnClickListener() {
        @Override
        public void onClick(View view) {
            DeviceManage.getInstance().stopSinglePreview();
            bStart = false;
            mPlayView.setVisibility(View.GONE);
            mPlayView.setVisibility(View.VISIBLE);
            return;
        }
    };

    @Override
    public void onBackPressed() {
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else if(content_sub.getVisibility() == View.VISIBLE) {
            content_sub.setVisibility(View.GONE);
            contentLayout.setVisibility(View.VISIBLE);
            mToolbar.setTitle(R.string.title_activity_main);
        }else {
            super.onBackPressed();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings){
            mAlarm.mRecyclerView.removeAllViews();
            mAlarm.mAlarmAdapter.removeAllData();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    public void addData(AlarmContent.AlarmItem item) {
        mAlarm.mAlarmAdapter.addData(0,item);
        mAlarm.mRecyclerView.scrollToPosition(0);
    }

    public void removeData(int position) {
        mAlarm.mAlarmAdapter.removeData(position);
    }

    @SuppressWarnings("StatementWithEmptyBody")
    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        // Handle navigation view item clicks here.
        int id = item.getItemId();

        if (id == R.id.nav_main) {
            // Handle the camera action
            content_sub.setVisibility(View.GONE);
            contentLayout.setVisibility(View.VISIBLE);
            mToolbar.setTitle(R.string.title_activity_main);
        } else if (id == R.id.nav_manage) {
            contentLayout.setVisibility(View.GONE);
            switchContent(mAlarm,mConfig);
            mToolbar.setTitle(R.string.title_manage);
        } else {
            if (id == R.id.nav_alarm) {
                contentLayout.setVisibility(View.GONE);
                switchContent(mConfig,mAlarm);
                mToolbar.setTitle(R.string.title_alarm);
            }
        }

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }


    class MainPageAdapter extends PagerAdapter {
        private List<View> mTabItems;
        @Override
        public int getCount() {
            return mTabItems.size();
        }

        public MainPageAdapter(List<View> tabItems) {
            mTabItems = tabItems;
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            container.addView(mTabItems.get(position));
            return mTabItems.get(position);
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View) object);
        }

        @Override
        public CharSequence getPageTitle(int position) {
            switch (position) {
                case 0:
                    return "预览&布防";
                case 1:
                    return "远程开锁";
                case 2:
                    return "对讲";
                default:
                    return "other";
            }
        }
    }
}